home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 331 / gemfsc14 / aessrc14 / aesfsel2.s < prev    next >
Text File  |  1989-07-22  |  21KB  |  462 lines

  1.  
  2. ;*========================================================================
  3. ;*
  4. ;* AESFAST Public Domain GEM bindings.
  5. ;*  Maintenance:
  6. ;*   02/11/89 v1.1: This source file is new with this version.
  7. ;*
  8. ;*   04/07/89 v1.2: 
  9. ;*            The calculation of the location of the prompt on the
  10. ;*            screen has been changed.  It was placed one boxchar height
  11. ;*            down on the screen, putting it right below the menu bar.
  12. ;*            This didn't look too good on a big-monitor system, so now
  13. ;*            it is calculated by centering the box, then subtracting a
  14. ;*            fixed offset from the centered Y to make it appear right
  15. ;*            above the fsel'er box.  The offset is 9 character heights,
  16. ;*            (plus 2 extra char heights for the prompt itself), less
  17. ;*            2 pixels (just to line everything up real neat).
  18. ;*
  19. ;*   07/22/89 v1.3:
  20. ;*            Bugfix...A 'bra.s' instruction was missing just before the
  21. ;*            'strcpy' routine, causing 4 bombs on a pre-1.4 machine.
  22. ;*========================================================================
  23.  
  24.           .include  "aesfast.sh"
  25.           .include  "gemfast.sh"
  26.           .extern   _gl_apversion
  27.           .extern   aesblock
  28.  
  29. ;*************************************************************************
  30. ;*
  31. ;* Extended fsel manager routine.
  32. ;*  (Including simulation routines for pre-TOS 1.4 systems).
  33. ;*
  34. ;*************************************************************************
  35.  
  36. ;-------------------------------------------------------------------------
  37. ; fsel_exinput
  38. ;  This function is new with TOS 1.4, but this binding supports it in all
  39. ;  TOS/AES versions with a simulation of the new routine's actions if the
  40. ;  AES version we're running under is pre-TOS 1.4
  41. ;-------------------------------------------------------------------------
  42.  
  43. _fsel_exinput::
  44.  
  45.           .cargs    #8,.pinpath.l,.pinsel.l,.pbutton.l,.plabel.l
  46.           link      a6,#-4
  47.  
  48.           move.w    _gl_apversion,d0         ; Check the AES version.  If
  49.           cmp.w     #$0104,d0                ; it's $0104, we're running
  50.           beq.s     .ramaes                  ; on the RAM-based TOS 1.4
  51.           cmp.w     #$0130,d0                ; Else, if it's less than $0130
  52.           blt       simu_exinput             ; we have to simulate exinput.
  53. .ramaes:
  54.           move.l    .plabel(a6),d0           ; Swap the button and prompt
  55.           move.l    .pbutton(a6),.plabel(a6) ; string pointers to make the
  56.           move.l    d0,.pbutton(a6)          ; addrin stuff contiguous.
  57.  
  58.           AControl  91,0,2,3                 ; AES v1.3 & up: fsel_exinput
  59.           moveq.l   #-4,d2                   ; is a legal function, do it.
  60.           lea       .pinpath(a6),a0          ; a0 -> addrin
  61.           ACall     RET2HERE                 ; Call AES.
  62.  
  63.           move.l    .plabel(a6),d0           ; Swap the prompt string and
  64.           move.l    .pbutton(a6),.plabel(a6) ; button pointers back to how
  65.           move.l    d0,.pbutton(a6)          ; they were on entry.
  66.  
  67.           moveq.l   #-4,d1                   ; Return values from
  68.           lea       .pbutton(a6),a1          ; intout[] array to caller
  69.           jmp       (a0)                     ; via aes_return routine.
  70.  
  71. ;*************************************************************************
  72. ; The following code and data supports the exinput simulation routines.
  73. ;
  74. ; The simulator supports *most* of the TOS 1.4 features, to wit:
  75. ;
  76. ;  - A prompt string of up to 30 chars is displayed with the file selector.
  77. ;  - The file selector handles <CR> like TOS 1.4 does (see comments below).
  78. ;  - If the caller passes in a path with a leading '\' it will be appended
  79. ;    to the current default drive & path (and the whole resulting string
  80. ;    will be returned upon exit).
  81. ;  - The current DTA is preserved.
  82. ;  - The current drive and path is preserved.
  83. ;
  84. ; These are differences between the simulator and TOS 1.4:
  85. ;
  86. ;  - There are no drive buttons in the dialog.
  87. ;  - There is still a static limit of 100 files that can be displayed.
  88. ;  - Long pathnames are NOT handled correctly.
  89. ;  - Multiple abort/continue situations will still give problems.
  90. ;  - The redraw sequence of the dialog is still the same.
  91. ;
  92. ; The things not supported are, of course, things I can't affect without
  93. ; completely re-writing the fsel_input handler.
  94. ;*************************************************************************
  95.  
  96. ;-------------------------------------------------------------------------
  97. ; Define variables which will be accessed as offsets from a3.
  98. ;  (Storage for these things will be allocated from the stack at runtime).
  99. ;-------------------------------------------------------------------------
  100.  
  101.           .abs                ; Define offsets from a3 base register...
  102.           
  103. savddrv:  ds.w      1         ; Save default drive.
  104. savdpath: ds.b      128       ; Save default path.
  105. savipath: ds.b      128       ; Save input path for compare after <CR>.
  106. savdta:   ds.l      1         ; Save pointer to current DTA.
  107. tmpdta:   ds.b      44        ; Temporary DTA for fsel_input to use.
  108. SAV_SZ    =  *                ; Size of a3-relative storage.
  109.  
  110. ;-------------------------------------------------------------------------
  111. ; Define variables which will be accessed as offsets from a5.
  112. ;  (Storage for these things is allocated in the text segment, below).
  113. ;-------------------------------------------------------------------------
  114.  
  115.           .abs                ; Define offsets from a5 base register...
  116.           
  117. prmpflag: ds.w      1         ; Flag: Has one-time object fixup been done?
  118.  
  119. treeptr:  ds.l      1         ; Ptr to tree: addrin for objc_draw() et. al.
  120. azero:    ds.w      1         ; A handy zero.
  121.  
  122. dialstuf: ds.w      1         ; Here things get a little ugly: The storage 
  123.           ds.w      2         ; from 'dialstuff' down is the intin array
  124. prmpstob: ds.w      1         ; for form_dial(FMD_FINISH).  From prmpstob
  125. prmpdpth: ds.w      1         ; down, it is also the intin array for
  126. prmpclip: ds.w      4         ; objc_draw().
  127.  
  128. lastkeyCR:ds.w      1         ; Flag: was last keystroke during fsel a <CR>?
  129.  
  130. ABS_SZ    =  *                ; Size of the a5-relative storage block.
  131.  
  132.           .text
  133.  
  134. absstore: dcb.b     ABS_SZ,0  ; Set aside memory for the a5-relative block.
  135.  
  136. ;-------------------------------------------------------------------------
  137. ; Define the TEDINFO and OBJECT structures for the prompt text. 
  138. ; (Macros for defining these things come from gemfast.sh).
  139. ;-------------------------------------------------------------------------
  140.  
  141. YSZ_PROMPT = 2
  142. YSZ_FSEL   = 9
  143. Y_OFFSET   = YSZ_PROMPT+YSZ_FSEL
  144.  
  145. prmptext: Teddef    0,0,0,3,0,TE_CNTR,$1180,0,1,31,0
  146. prmptree: Treedef   text
  147.           Objdef    ,-1,-1,-1,G_BOXTEXT,LASTOB,NORMAL,0,0,0,40,YSZ_PROMPT
  148.  
  149. ;-------------------------------------------------------------------------
  150. ; This routine is installed as a hook in the BIOS vector for the duration
  151. ; of the the fsel_input call.  It watches for a Bconin(2) call (which will
  152. ; be the AES asking for a character).  The Bconin call is done from in
  153. ; here such that we get the character back from the real BIOS and examine
  154. ; it.  If the character is a <CR>, we set the flag to say so and return
  155. ; the character to the caller.  If not a <CR> we clear the flag and 
  156. ; return the character.
  157. ;
  158. ; The whole reason for this is a bug in the pre-TOS 1.4 AES: If the user
  159. ; edited the path but didn't click the mouse on anything or change the
  160. ; filename field, then hit <CR>, the system returned a CANCEL status. This
  161. ; BIOS hook is the only way to tell for sure that the exit was via <CR>.
  162. ;-------------------------------------------------------------------------
  163.  
  164. oldbios:  dc.l      0         ; Old BIOS vector address.
  165.  
  166. bioshook:
  167.           lea       6(sp),a0            ; Assume super mode caller.
  168.           btst.b    #5,(sp)             ; Were we in super mode?
  169.           bne.s     .supermode          ; No, user mode...
  170.           move.l    usp,a0              ; So look at parms on user stack.
  171. .supermode:
  172.           move.l    #$00020002,d0       ; Bconin(2) function...
  173.           cmp.l     (a0),d0             ; Is it that?
  174.           bne.s     .biospunt           ; Nope, punt.
  175.  
  176.           move.l    d0,-(sp)            ; Stack Bconin(2) function code,
  177.           bsr.s     .bioscall           ; Go get the character.
  178.           addq.l    #4,sp
  179.           
  180.           lea       absstore(pc),a0     ; Point to common storage base.
  181.           cmp.b     #'\r',d0            ; Is the char a <CR>? If so set the
  182.           seq       lastkeyCR(a0)       ; flag, either way, return the char.
  183. .biosreturn:  
  184.           rte                           ; Return the char to the caller.
  185.  
  186. .bioscall:                              ; Call original BIOS, with return
  187.           move.w    sr,-(sp)            ; to caller of 'bioscall'.
  188. .biospunt:                              
  189.           move.l    oldbios(pc),-(sp)   ; Not a BIOS function we handle,
  190.           rts                           ; punt control to the real BIOS.
  191.           
  192. ;-------------------------------------------------------------------------
  193. ; This routine lets us call AES more quickly than going through the
  194. ; routines in AESCOMN (and is better tailored to our needs here).
  195. ;-------------------------------------------------------------------------
  196.           
  197. aes_icall:
  198.            
  199.           movep.l   d0,control+1(a4)    ; fill in the control array (!),
  200.           move.l    a0,padrin(a4)       ; store the adrin ptr into aespb
  201.           move.l    a1,pintin(a4)       ; store the intin ptr into aespb
  202.           move.l    a2,pintout(a4)      ; store it into aespb
  203.           move.l    a4,d1               ; move the aespb pointer to the
  204.           move.w    #$C8,d0             ; interface register, also the AES
  205.           trap      #2                  ; function code, call AES, return
  206.           rts                           ; to the calling binding routine.
  207.  
  208. ;-------------------------------------------------------------------------
  209. ; simu_exinput - Simulate an exinput call on pre-TOS 1.4 systems.
  210. ;-------------------------------------------------------------------------
  211.  
  212. simuregs  reg       a2-a5               ; Registers we use.
  213.  
  214. simu_exinput:
  215.  
  216.           movem.l   #simuregs,-(sp)     ; Save registers.
  217.           lea       absstore(pc),a5     ; Load storage base register.
  218.           lea       aesblock,a4         ; Load aesblock base register.
  219.           
  220.           tas       prmpflag(a5)        ; Has first-time object tree fixup
  221.           bne       do_simulation       ; been done?  If so, continue below.
  222.  
  223. ;-------------------------------------------------------------------------
  224. ; Do the one-time object tree fixup:
  225. ;
  226. ;  - Plug in the various static string pointers.
  227. ;  - Plug in a couple of static integer values.
  228. ;  - Call rsrc_obfix  for resolution-specific x/y/w/h fixup.
  229. ;  - Call form_center to center box in the x coord & calc the clip area.
  230. ;  - Call graf_handle to get the height of a boxchar, and use this height
  231. ;    as the ob_y of the prompt box (and the clip area).  It just so happens
  232. ;    that the AES menu bar is one 'boxchar' in height, so this guarantees
  233. ;    we never overlay the menu bar with our prompt.
  234. ;-------------------------------------------------------------------------
  235.          
  236.           lea       azero(a5),a1        ; To do fixup, set string pointers
  237.           lea       prmptext(pc),a0     ; in TEDINFO and OBJECT structures.
  238.           move.l    a1,te_ptmplt(a0)    ; The template and valid strings
  239.           move.l    a1,te_pvalid(a0)    ; are NULL.  The ob_spec pointer
  240.           lea       prmptree(pc),a3     ; in the tree must point to the
  241.           move.l    a0,ob_spec(a3)      ; TEDINFO structure.
  242.           move.l    a3,treeptr(a5)      ; Save the tree pointer.
  243.  
  244.           move.w    #MAX_DEPTH,prmpdpth(a5)   ; Set objc_draw max-depth.
  245.           move.w    #FMD_FINISH,dialstuf(a5)  ; Set form_dial type.
  246.           
  247.           subq.l    #2,sp               ; allocate intout[1] 
  248.           move.l    sp,a2               ; a2 -> intout
  249.           lea       azero(a5),a1        ; a1 -> intin 
  250.           lea       treeptr(a5),a0      ; a0 -> adrin
  251.           AControl  114,1,1,1           ;    rsrc_obfix(prmptree,R_TREE);
  252.           bsr       aes_icall           ; do it.
  253.           addq.l    #2,sp               ; we don't care about intout[0].
  254.  
  255.           sub.w     #10,sp              ; Allocate intout[5] 
  256.           move.l    sp,a2               ; a2 -> intout
  257.           lea       treeptr(a5),a0      ; a0 -> addrin (prmptree)
  258.           AControl  54,0,5,1            ;    form_center(prmptree, &stack);
  259.           bsr       aes_icall           ; do it.
  260.           addq.l    #2,sp               ; We don't care about intout[0],
  261.           move.l    (sp)+,prmpclip(a5)  ; the rest of intout is the
  262.           move.l    (sp)+,prmpclip+4(a5); clip rectangle, save it.
  263.  
  264.           sub.w     #10,sp              ; Allocate intout[5], make a2 point
  265.           move.l    sp,a2               ; to it.  Do graf_handle(&stack).
  266.           AControl  77,0,5,0            ; The only value we want back from
  267.           bsr       aes_icall           ; the call is the height of a char
  268.           addq.l    #4,sp               ; which is in intout[2], put that
  269.           move.w    (sp)+,d0            ; in d0, throw everything else away.
  270.           addq.l    #4,sp               ; Calc the placement of the prompt
  271.           mulu      #Y_OFFSET,d0        ; box as Y_OFFSET characters up from
  272.           subq.w    #2,d0               ; the current (centered) location,
  273.           sub.w     d0,ob_y(a3)         ; set the ob_y value in the tree
  274.           sub.w     d0,prmpclip+2(a5)   ; and clip rectange to this value.
  275.  
  276.           bra.s     do_simulation       ; Continue with simulation below.
  277.  
  278. strcpy:
  279.           move.b    (a0)+,(a1)+
  280.           bne.s     strcpy
  281.           rts
  282.  
  283. strcmp:
  284.           move.b    (a0)+,d0
  285.           beq.s     .checkdone
  286.           cmp.b     (a1)+,d0
  287.           beq.s     strcmp
  288.           rts
  289. .checkdone:
  290.           tst.b     (a1)
  291.           rts
  292.  
  293. ;-------------------------------------------------------------------------
  294. ; Once the one-time stuff is done (and on all subsequent calls...) do
  295. ; the actual simulation of the TOS 1.4 exinput:
  296. ;
  297. ;  - Plug the prompt string pointer into the TEDINFO.
  298. ;  - The current default drive and path is saved.
  299. ;  - The current DTA address is saved, and a temporary DTA is installed.
  300. ;  - If the pathname passed to exinput starts with a '\', the passed-in
  301. ;    path is appended to the current default path.
  302. ;  - A hook is placed into the BIOS vector to watch for <CR> being hit,
  303. ;    so that we can mimick the new fsel's actions when just the pathname
  304. ;    is edited, and the user hits <CR> (to move to the filename field).
  305. ;  - The prompt string is placed in a box above the fsel dialog box on the
  306. ;    screen (but below the menu bar) before the system fsel'er is called.
  307. ;    The prompt is displayed inside a box, (it's a BOXTEXT object, which
  308. ;    is the entire tree).  The prompt is displayed with an objc_draw, and
  309. ;    removed by sending a redraw message (via form_dial).
  310. ;  - Call fsel_input() (the old one).
  311. ;  - Check to see if our BIOS hook set the flag saying a <CR> was the last
  312. ;    key hit.  If so, see if the pathname in the fsel dialog was changed.
  313. ;    If so, the user probably hit <CR> after typing the path (I always do),
  314. ;    so we loop back to do the fsel dialog again.  If the user clicked on
  315. ;    OK instead of hitting return, this won't happen.  Also, if the user
  316. ;    doesn't change the path (but perhaps does change the filename), then
  317. ;    hits return, we will not repeat the dialog.
  318. ;  - Call form_dial() to send a redraw message to clear the prompt box.
  319. ;  - Restore the current drive & path, and the old DTA.
  320. ;  - De-install the BIOS hook.
  321. ;  - Return to caller.
  322. ;-------------------------------------------------------------------------
  323.  
  324. do_simulation:
  325.  
  326.           .cargs    #8,.pinpath.l,.pinsel.l,.pbutton.l,.plabel.l
  327.  
  328.           sub.w     #SAV_SZ,sp          ; Allocate save area from stack,
  329.           move.l    sp,a3               ; load save area base register.
  330.                     
  331.           move.w    #$19,-(sp)
  332.           trap      #1
  333.           addq.l    #2,sp
  334.           move.w    d0,savddrv(a3)
  335.           add.b     #'A',d0
  336.           move.b    d0,savdpath(a3)
  337.           move.b    #':',1+savdpath(a3)
  338.           
  339.           clr.w     -(sp)
  340.           pea       2+savdpath(a3)
  341.           move.w    #$47,-(sp)
  342.           trap      #1
  343.           addq.l    #8,sp
  344.           
  345.           tst.b     2+savdpath(a3)
  346.           bne.s     .gotpath
  347.           move.w    #$5C00,2+savdpath(a3)         ; 5C00 == "\<NULL>"
  348.  
  349. .gotpath:
  350.  
  351.           move.w    #$2F,-(sp)
  352.           trap      #1
  353.           move.l    d0,savdta(a3)
  354.           addq.l    #2,sp
  355.  
  356.           pea       tmpdta(a3)
  357.           move.w    #$1A,-(sp)
  358.           trap      #1
  359.           addq.l    #6,sp
  360.  
  361.           move.l    .pinpath(a6),a0     ; a0 -> input path
  362.           lea       savipath(a3),a1     ; a0 -> path save area
  363.           cmp.b     #'\\',(a0)          ; Leading '\' in input path?
  364.           bne.s     .copypath           ; Nope, go do straight copy.
  365.           lea       savdpath(a3),a0     ; Yep, so copy the current
  366.           bsr       strcpy              ; default path to the save
  367.           cmp.b     #'\\',-2(a1)
  368.           bne.s     .noterm
  369.           subq.l    #1,a1
  370. .noterm:
  371.           move.l    .pinpath(a6),a0     ; area first, then concat
  372.           subq.l    #1,a1               ; the input path onto the 
  373.           bsr       strcpy              ; end of it.  Since we changed
  374.           lea       savipath(a3),a0     ; it in the save area, we need to
  375.           move.l    .pinpath(a6),a1     ; copy it back to the input area.
  376. .copypath:
  377.           bsr       strcpy
  378.  
  379.           lea       prmptext(pc),a0     ; a0 -> te_ptext in TEDINFO.
  380.           move.l    .plabel(a6),(a0)    ; Set prompt text pointer.
  381.           
  382.           subq.l    #2,sp               ; allocate intout[1]
  383.           move.l    sp,a2               ; a2 -> intout
  384.           lea       prmpstob(a5),a1     ; a1 -> intin
  385.           lea       treeptr(a5),a0      ; a0 -> addrin
  386.           AControl  42,6,1,1            ;    objc_draw(prmptree,R_TREE....);
  387.           bsr       aes_icall           ; do it.
  388.           addq.l    #2,sp               ; throw away intout[0].
  389.           
  390.           pea       bioshook(pc)
  391.           move.w    #$2D,-(sp)
  392.           move.w    #5,-(sp)
  393.           trap      #13
  394.           addq.l    #8,sp
  395.           lea       oldbios(pc),a0
  396.           move.l    d0,(a0)
  397.  
  398. .fsel_loop:
  399.  
  400.           clr.w     lastkeyCR(a5)       ; Clear <CR> flag.
  401.           
  402.           lea       -4(a6),a2           ; a2 -> intout
  403.           lea       .pinpath(a6),a0     ; a0 -> addrin          
  404.           AControl  90,0,2,2            ;    fsel_input(inpath, insel,...);
  405.           bsr       aes_icall           ; do it.
  406.  
  407.           tst.w     lastkeyCR(a5)       ; Hack to fix an AES bug: If our
  408.           beq.s     .fsel_done          ; BIOS hook says the last key was
  409.           move.w    #1,-2(a6)           ; a CR, force the button to OK.
  410.  
  411.           move.l    .pinpath(a6),a0
  412.           lea       savipath(a3),a1
  413.           bsr       strcmp
  414.           beq.s     .fsel_done
  415.           
  416.           move.l    .pinpath(a6),a0
  417.           lea       savipath(a3),a1
  418.           bsr       strcpy
  419.           bra.s     .fsel_loop
  420.           
  421. .fsel_done:
  422.  
  423.           subq.l    #2,sp               ; allocate intout[1] for form_dial
  424.           move.l    sp,a2               ; a2 -> intout
  425.           lea       dialstuf(a5),a1     ; a1 -> intin
  426.           AControl  51,9,1,0            ;    form_dial(FMD_FINISH,...);
  427.           bsr       aes_icall           ; this sends a redraw message to
  428.           addq.l    #2,sp               ; clean up our prompt text box.
  429.  
  430.           move.w    savddrv(a3),-(sp)
  431.           move.w    #$0E,-(sp)
  432.           trap      #1
  433.           addq.l    #4,sp
  434.           
  435.           pea       savdpath(a3)
  436.           move.w    #$3B,-(sp)
  437.           trap      #1
  438.           addq.l    #6,sp
  439.  
  440.           move.l    savdta(a3),-(sp)
  441.           move.w    #$1A,-(sp)
  442.           trap      #1
  443.           addq.l    #6,sp
  444.  
  445.           move.l    oldbios(pc),-(sp)
  446.           move.w    #$2D,-(sp)
  447.           move.w    #5,-(sp)
  448.           trap      #13
  449.           addq.l    #8,sp
  450.  
  451.           add.w     #SAV_SZ,sp          ; Deallocate save area from stack.
  452.           movem.l   (sp)+,#simuregs     ; Restore working regs.
  453.           
  454.           move.l    .pbutton(a6),a1     ; Return the values from
  455.           move.w    -4(a6),d0           ; intout to the caller.
  456.           move.w    -2(a6),(a1)
  457.           unlk      a6
  458.           rts
  459.  
  460. ;         end of code
  461.  
  462.